package com.zeus.core.report;

import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.classic.spi.IThrowableProxy;
import ch.qos.logback.classic.spi.ThrowableProxy;
import com.zeus.common.enums.ZeusEventTypeEnum;
import com.zeus.common.utils.StackTraceUtils;
import com.zeus.core.open.event.ZeusEvent;

/**
 * Logback上报工具
 *
 * @author f1ybear_wang  2022/2/22 7:50 下午
 */
public class ZeusReportLogbackClient extends AbstractLogZeusReportClient {
    /**
     * 日志信息
     */
    private ILoggingEvent loggingEvent;

    public ZeusReportLogbackClient(ILoggingEvent loggingEvent) {
        super();
        this.loggingEvent = loggingEvent;
        this.zeusEvent = ZeusEvent.builder().eventType(eventType()).message(loggingEvent.getFormattedMessage()).build();
    }

    @Override
    public ZeusEventTypeEnum eventType() {
        return ZeusEventTypeEnum.LOGBACK_EVENT;
    }

    @Override
    protected void parsingExtend() {
        if (this.parsingExtendInit || this.loggingEvent == null) {
            return;
        }
        // 初始化基础数据
        this.message = this.loggingEvent.getFormattedMessage();
        this.loggerName = this.loggingEvent.getLoggerName();
        this.occurrenceTime = this.loggingEvent.getTimeStamp();

        // 初始化文件名、方法名、行号
        StackTraceElement[] callerData = this.loggingEvent.getCallerData();
        if (callerData != null && callerData.length > 0 && callerData[0] != null) {
            this.fileName = callerData[0].getFileName();
            this.methodName = callerData[0].getMethodName();
            this.lineNumber = String.valueOf(callerData[0].getLineNumber());
        }

        // 获取异常
        IThrowableProxy iThrowableProxy = this.loggingEvent.getThrowableProxy();
        if (iThrowableProxy instanceof ThrowableProxy) {
            ThrowableProxy throwableProxy = (ThrowableProxy)iThrowableProxy;
            Throwable ex = throwableProxy.getThrowable();
            if (ex != null && ex.getStackTrace() != null && ex.getStackTrace().length > 0) {
                this.exceptionMessage = ex.getMessage();
                this.stackTrace = StackTraceUtils.getStackTrace(ex);

                if (this.fileName == null || this.fileName.isEmpty()) {
                    this.fileName = ex.getStackTrace()[0].getFileName();
                }
                if (this.methodName == null || this.methodName.isEmpty()) {
                    this.methodName = ex.getStackTrace()[0].getMethodName();
                }
                if (this.lineNumber == null) {
                    this.lineNumber = String.valueOf(ex.getStackTrace()[0].getLineNumber());
                }
            }
        }
        this.gatherRule.setAlarmLevel(this.message, this.loggerName, this.exceptionMessage, this.stackTrace);
        this.parsingExtendInit = true;
    }
}
